package com.bgyrobot.coordinate.model;

import com.alibaba.fastjson.annotation.JSONField;
import com.bgyrobot.coordinate.util.MatrixUtil;

import lombok.Data;

@Data
public class CoordinateTransform {
    
    public static final CoordinateTransform SAME = new CoordinateTransform("", "", null,  
            new double[][] {{1.0, 0.0, 0.0, 0.0}, {0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 0.0, 1.0}});
    
    public static final String hashString(String srcCS, String tgtCS, ReferencePoint refPoint) {
        return refPoint == null
                ? String.format("%s->%s", srcCS, tgtCS)
                : String.format("%s->%s;%s", srcCS, tgtCS, ReferencePoint.hashString(refPoint.getRefCS(), refPoint.getRefCoord()));
    }
    
    /**
     * 源坐标系名称
     */
    @JSONField(name="SrcCS")
    private String srcCS;

    /**
     * 目标坐标系名称
     */
    @JSONField(name="TgtCS")
    private String tgtCS;
    
    /**
     * 参考点坐标系点
     */
    @JSONField(name="RefPoint")
    private ReferencePoint refPoint;

    /**
     * 变换矩阵
     */
    @JSONField(name="Matrix")
    private double[][] matrix;
    
    @Override
    public String toString() {
        return CoordinateTransform.hashString(srcCS, tgtCS, refPoint);
    }
    
    @Override
    public boolean equals(Object anObject) {
        if (anObject instanceof CoordinateTransform) {
            return CoordinateTransform.hashString(srcCS, tgtCS, refPoint).equalsIgnoreCase(anObject.toString());
        }
        return false;
    }
    
    @Override
    public int hashCode() {
        return CoordinateTransform.hashString(srcCS, tgtCS, refPoint).hashCode();
    }
    
    public CoordinateTransform(String srcCS, String tgtCS) {
        this.srcCS = srcCS;
        this.tgtCS = tgtCS;
        this.refPoint = null;
        this.matrix = null;
    }
    
    public CoordinateTransform(String srcCS, String tgtCS, ReferencePoint refPoint) {
        this.srcCS = srcCS;
        this.tgtCS = tgtCS;
        this.refPoint = refPoint;
        this.matrix = null;
    }
    
    public CoordinateTransform(String srcCS, String tgtCS, ReferencePoint refPoint, double[][] matrix) {
        this.srcCS = srcCS;
        this.tgtCS = tgtCS;
        this.refPoint = refPoint;
        this.matrix = matrix;
    }
    
    public CoordinateTransform reverse() {
        return new CoordinateTransform(tgtCS, srcCS, refPoint, matrix == null ? null : MatrixUtil.inverseMatrix(matrix));
    }
}
